package com.meituan.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.google.gson.JsonObject;
import com.meituan.pojo.dto.OrderMessageReq;
import com.meituan.pojo.resp.BaseResp;
import com.meituan.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

@RequestMapping("/pay")
@Controller
public class PayController {

    @Autowired
    OrderService orderService;

    private static final String privateKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCCR50SacmEEMCmnO+A1xS/5lVW00CHUnB0Cob+gu0XVvRNPkR5JQXmDW1KehXajxb02nDLsh8kwHq++5FoWrLwxsvZNmn36skdXvWLY6iY6lA7p3J6qvSp+F3O/D2dD3Pz5BsZxBSTwDPMp7lEL/0B/EJG9QEYrSUfC3S9MYUehkuesM4bBvQW3tzpLZN93F+unY6ANNx+Si6tT08+al4/2TuIa2RndZIzNnZURsrQBaT9NU0SQKzkI95y8IM40J97d/hoEGGg1P6PxSrNJaW5vU6ddfRc8Y+1+n7chtjxBajlSB2s4ssb8px1FQ5Lgqb/TfubvZabzJR+JDW/fEWJAgMBAAECggEANowliAAjD9iz0Q8EeL2VQoP+V0w8SGyMCQofW5EWFB+kSnM32EFYJuqYSAa1/7zJr9uGPsNlps2wlyZdy4OuSIHz+A6Ab/0uF84aoTIo9V2mGlQR6qqJpmEHZhLW+VvvAL8RWchvlS10gsv3FkXBeYNVfMA4pUxZrpXtWwnQ4uZXFmL+fxnb2lkJOsqSR0XVkVTuRhcgw7tsmWfFGCWRQXNIKSYvqUr+0TcjVNgtFsu/y+Mc9B9hlLv2cWj/9dQsyK1RvfB9s9RUh9b12nJHUrrIqBN7A9Pd5FuZXpEXhypvmM6pkyLC1fXlvakxqlcd+S8ZDA3BVT10hlgbW7T3wQKBgQD7XCDHT9B7VVmpiVz0udjmAmYSgWwOpQ6UkzY4+35ys01Q9AVftef4Pq6sDy4DD1skVu6m+LTgpRijkiHOM6ATeb6g53ceC/g5z9eVbOgJ90EtGXth0KKtiTOC+0XYERfDTlAtpQm7J83WEA5/HUpbHaTemi4of0W3AcDR0xY2jwKBgQCEr0mGZqzkCuqFvHoR/FzE1qk7jntq7gReWTLsw8rX7dQ5IS02jhOSOnuoH9IoMPwXpAJ/q2sN4x2ipWcZo9OGz8XuwhueTEwyM4GIYFBmbFX15tUTmXRVolB73BTDJhGCcYSHX/O55GOCSzYu3iDuu8Xm3av3HUjTmTqfmKeOZwKBgQDsb7ZthMgomxoh/RGxKXe6s5rr4U2RYPUcEHU6mGZS4hHiCgdcBjHTMrL/KbAwNKuYvSTzbpJFlUZd5kFiQvFaIHSNyewkGUI+ryCsb6q8ZRWrpIKIecXr0ljf5hfGrB1cGzgUF1/V6hUWPDhGnXipyHKi6QhuE3myMTX8qMAGRQKBgCAAHp15me0N7O4APPilgsI+e2ZPwNhTO1596NhNiFh3lZ2JsNvdfD7iN/yeYBMtbT9OYQPlldYtlnIpriny5ws2hShGTF7rS903qt/3SqzJKBo8Z9toQTR+Byc4NxGx1rs9IZd8vs1wlcdQ2GqJTCwHwX0irVzWBUBzTj47lP21AoGANxxR4dFwuFuAkKYduYgwsT7TYKukMqJms4w4OJrFV985/VINR3AadTKtrOHhc4LI0DGWWxiiX03YdplEm3rJKJ5goqiX6JGUIxxrcSC02nn2wwheQwYqxybk9e+c7h5xYVNlTQ1IKI7f+wk+JRXPJGFW3LyGDnwICnYbrPgzX6Q=";
    private static final String alipaypubicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAj27oK9zZoFe+Llb9LStknbE/BO68yOQMxjUBMLq6bgysUdcb2uBwji6Iw5T8lm+xPhLyejb/a3U73c2pt88+HQjCsyz4de07kMAaSF3pR0p/d6+43mjW0GZmYUy+9RVToay42ZXgcJ1IsnnmgsuIUGfclJrLnmL4BqdOD6n1Fvk/eMRo3fz502iXpP4BoUPqQOhd1+LKCsFjKzz3E8cCZZkH5y1DgxJT+Trrz3tBl+xXsQfZL00uSWctq9oG84brCaoTDcXXez1PKM91lDyCQ2/1vxumpQOe4bk00jwjBr1J9xbpRa6Aj/19GS01kK/BG+iQcpzwjLo9XJDwmkE6xwIDAQAB";
    private OrderMessageReq orderMessageReq = null;

    @RequestMapping("addPayMessage")
    @ResponseBody
    public BaseResp addPayMessage(@RequestBody OrderMessageReq orderMessageReq){
        if (orderMessageReq!=null){
            this.orderMessageReq = orderMessageReq;
            return new BaseResp().SUCCESS();
        }
        return new BaseResp().ERROR();
    }

    @RequestMapping("/alipay")
    public void pay(HttpServletRequest httpRequest, HttpServletResponse httpResponse) throws IOException {
//        System.out.println("-------------------");
//        public   void   doPost() throws ServletException, IOException  {
//        生成支付宝请求客户端
//        1.serverUrl 代表请求的支付宝网关地址
//        2.APP_ID   商户申请的唯一标识
//        3.APP_PRIVATE_KEY 应用私钥
//        4.FORMAT  格式转换    json
//        5.CHARSET 编码格式  utf-8
//        6.ALIPAY_PUBLIC_KEY   支付宝公钥
//        7.SIGN_TYPE   加密方式    RSA2
            AlipayClient alipayClient =  new DefaultAlipayClient( "https://openapi.alipaydev.com/gateway.do" , "2021000121672899", privateKey, "json", "utf-8", alipaypubicKey, "RSA2");  //获得初始化的AlipayClient
//        声明交易方式，网页端支付
            AlipayTradePagePayRequest alipayRequest =  new  AlipayTradePagePayRequest(); //创建API对应的request
//        returnurl 支付宝同步返回的参数
            alipayRequest.setReturnUrl( "http://localhost:8081/#/success" );
//        NotifyUrl 支付宝的异步通知
            alipayRequest.setNotifyUrl( "http://81.70.62.178:8080/pay/notifyUrl" ); //在公共参数中设置回跳和通知地址
//        支付宝的参数
//        out_trade_no  订单号——必须保持唯一
//        product_code  固定为 FAST_INSTANT_TRADE_PAY
//        total_amount  价格
//        subject       主题
//        body          内容
//        再下边不需要
        JSONObject jsonObject = new JSONObject();
//        jsonObject.put("out_trade_no", UUID.randomUUID().toString());
        jsonObject.put("out_trade_no", this.orderMessageReq.getOid());
        jsonObject.put("product_code", "FAST_INSTANT_TRADE_PAY");
        jsonObject.put("total_amount", this.orderMessageReq.getMoney());
        jsonObject.put("subject", this.orderMessageReq.getSname());
        jsonObject.put("subject", this.orderMessageReq.getGname()+"--   *"+this.orderMessageReq.getGnum());
        alipayRequest.setBizContent(jsonObject.toJSONString()); //填充业务参数
            String form= "" ;
            try  {
//                请求支付宝获取到支付的表单
                form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
            }  catch  (AlipayApiException e) {
                e.printStackTrace();
            }
            httpResponse.setContentType( "text/html;charset=utf-8");
            httpResponse.getWriter().write(form); //直接将完整的表单html输出到页面
            httpResponse.getWriter().flush();
            httpResponse.getWriter().close();
//        }
    }

    @RequestMapping("/notifyUrl")
    public void notfiyUrl(HttpServletRequest request) throws AlipayApiException {
        //将异步通知中收到的所有参数都存放到map中 将Request请求中的参数重组为map集合
        Map<String, String> paramsMap = convertRequestParamsToMap(request);

        boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, alipaypubicKey, "utf-8", "RSA2"); //调用SDK验证签名
        if(signVerified){
            // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
            System.out.println("验签成功！！！");
            System.out.println("当前回调的订单编号为:"+paramsMap.get("out_trade_no"));
            System.out.println("当前回调的appid为:"+paramsMap.get("app_id"));
            System.out.println("当前订单支付的金额为:"+paramsMap.get("total_amount"));
            System.out.println("当前订单状态为:"+paramsMap.get("trade_status"));
            //通过订单号更改数据库的该笔订单的交易状态

            String out_trade_no = paramsMap.get("out_trade_no");
            int i = Integer.parseInt(out_trade_no);
            if (paramsMap.get("trade_status").equals("TRADE_SUCCESS")||paramsMap.get("trade_status").equals("TRADE_FINISHED")){
                boolean b = orderService.payComplete(i);
                if (b){
                    System.out.println("支付成功");
                }else {
                    System.out.println("支付失败");
                }
            }
        }else{
            // TODO 验签失败则记录异常日志，并在response中返回failure.
        }
    }



    // 将request中的参数转换成Map
    private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
        Map<String, String> retMap = new HashMap<String, String>();

        Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();

        for (Map.Entry<String, String[]> entry : entrySet) {
            String name = entry.getKey();
            String[] values = entry.getValue();
            int valLen = values.length;

            if (valLen == 1) {
                retMap.put(name, values[0]);
            } else if (valLen > 1) {
                StringBuilder sb = new StringBuilder();
                for (String val : values) {
                    sb.append(",").append(val);
                }
                retMap.put(name, sb.toString().substring(1));
            } else {
                retMap.put(name, "");
            }
        }

        return retMap;
    }
}
